//
//  Token.swift
//  App
//
//  Created by melvyn on 2018/8/19.
//

import Vapor
import Fluent
import Crypto

struct Token: Codable {
    
    var id: Int?
    var token: String
    var uid: User.ID
    var createdAt: Date?
    var updatedAt: Date?
    
    init(token: String, uid: User.ID) {
        self.token = token
        self.uid = uid
    }
}

extension Token: Entity {
    static var createdAtKey: TimestampKey? {
        return \.createdAt
    }
}
extension Token: Content {}
extension Token: Migration {}

extension Token {
    var userRef: Parent<Token, User> {
        return parent(\.uid)
    }
}

extension Token {
    static func generate(for user: User) throws -> Token {
        let random = try CryptoRandom().generateData(count: 16)
        return try Token(token: random.base64EncodedString(), uid: user.requireID())
    }
}

import Authentication
extension Token: Authentication.Token {
    
    typealias UserType = User
    typealias UserIDType = User.ID
    
    static var userIDKey: WritableKeyPath<Token, User.ID> {
       return \Token.uid
    }
    
    static var tokenKey: WritableKeyPath<Token, String> {
        return \Token.token
    }
}

extension Token: BearerAuthenticatable {}


extension Token {
    struct Public {
        var user: User.Public
        var token: Token
    }
}
extension Token.Public: Content {}
